#pragma once
#include <iostream>
#include <pthread.h>
#include <string>
#include <functional>
#include <cstdio>
#include <unistd.h>

namespace ThreadModule
{
    static int cnt = 1;
    class Thread
    {
        using func_t = std::function<void()>;

        enum class STATUS
        {
            NEW,
            RUNNING,
            STOP,
            JOIN
        };

        static void *DefaultFunc(void *args)
        {
            Thread *_this = static_cast<Thread *>(args);
            std::cout << _this->Name() << std::endl;
            _this->_func();
            return nullptr;
        }

    public:
        Thread(func_t func)
            : _func(func), _tid(-1), _pid(-1), _status(STATUS::NEW), _isDetach(false)
        {
            char name[1024];
            snprintf(name, sizeof(name), "这是Thread-%d", cnt++);
            _name = name;
        }

        bool Start()
        {
            if (_status != STATUS::RUNNING)
            {
                int n = pthread_create(&_tid, nullptr, DefaultFunc, this);
                if (n == 0)
                {
                    _pid = getpid();
                    _status = STATUS::RUNNING;
                    return true;
                }
            }
            return false;
        }

        bool Stop()
        {
            if (_status == STATUS::RUNNING)
            {
                int n = pthread_cancel(_tid);
                if (n == 0)
                {
                    _status = STATUS::STOP;
                    return true;
                }
            }
            return false;
        }

        bool Detach()
        {
            if (_status == STATUS::RUNNING && !_isDetach)
            {
                int n = pthread_detach(_tid);
                if (n == 0)
                {
                    _isDetach = true;
                    return true;
                }
            }
            return false;
        }

        bool Join()
        {
            if (!_isDetach && _status == STATUS::RUNNING)
            {
                int n = pthread_join(_tid, nullptr);
                if (n == 0)
                {
                    _status = STATUS::JOIN;
                    //std::cout << "线程" << _tid << ",退出完毕" << std::endl;
                    return true;
                }
            }
            return false;
        }

        bool IsDetach()
        {
            return _isDetach;
        }

        const std::string &Name()
        {
            return _name;
        }

    private:
        std::string _name;
        pthread_t _tid;
        pid_t _pid;
        func_t _func;
        STATUS _status;
        bool _isDetach;
    };
}